<script setup lang="ts">
import { Delete } from '@element-plus/icons-vue';
import { computed, ref, watch } from 'vue';
import router from '../../router';
import { TabsPaneContext } from 'element-plus';
import { RouteLocationNormalizedGeneric } from 'vue-router';

const cls = 'ui-layout-tabs'

const tabs = ref<string[]>([])

const current = ref('')

const getRoute = (path: string | undefined) => path === undefined ? path : router.resolve(path)

const HOME_PATH = '/'

const isHome = (path: string) => getRoute(path)?.name === 'home'

const getLabel = (path: string) => getRoute(path)?.meta.title ?? '未命名页面'

const closable = computed(() => {
  const arr = tabs.value
  return arr.length > 1 || !isHome(arr[0])
})

const onTabClick = (pane: TabsPaneContext) => router.push(pane.props.name as string)

const onTabRemove = (path: any) => {
  const arr = tabs.value
  const index = arr.indexOf(path)
  const nextTab = arr[index - 1] || arr[index + 1]
  arr.splice(index, 1)
  if (path === current.value) {
    router.push(nextTab || HOME_PATH)
  }
}

const actions = [
  {
    label: '关闭当前',
    action: () => {
      const curTab = current.value
      curTab && closable.value && onTabRemove(curTab)
    }
  },
  {
    label: '关闭其它',
    action: () => {
      tabs.value = [current.value || HOME_PATH]
    }
  },
  {
    label: '全部关闭',
    action: () => {
      tabs.value = []
      router.push(HOME_PATH)
    }
  }
]

const onRouteChange = (r: RouteLocationNormalizedGeneric) => {
  if (r.matched.length < 1) return
  if (r.meta.notTab) return
  const arr = tabs.value
  const curIndex = arr.indexOf(current.value)
  const tar = r.fullPath
  const tarLastMatched = [...r.matched].pop()
  const tarIndex = tarLastMatched
    ? arr.findIndex(_ => {
      const item = getRoute(_)
      const lastMatched = [...(item?.matched ?? [])].pop()
      return lastMatched && lastMatched.path === tarLastMatched.path
    })
    : -1
  current.value = tar
  if (tarIndex < 0) {
    curIndex < 0 ? arr.push(tar) : arr.splice(curIndex + 1, 0, tar)
  } else {
    arr.splice(tarIndex, 1, tar)
  }
}

watch(() => router.currentRoute.value, onRouteChange, { immediate: true })
</script>

<template>
  <div :class="cls">
    <ElTabs
      type="card"
      :editable="closable"
      v-model="current"
      @tab-click="onTabClick"
      @tab-remove="onTabRemove">
      <template #add-icon>
        <ElDropdown>
          <ElLink :class="`${cls}_delete`" :underline="false" :icon="Delete" />
          <template #dropdown>
            <ElDropdownMenu>
              <ElDropdownItem v-for="_ in actions" :key="_.label" :class="`${cls}_dropdown-item`">
                <ElLink :underline="false" @click="_.action">{{ _.label }}</ElLink>
              </ElDropdownItem>
            </ElDropdownMenu>
          </template>
        </ElDropdown>
      </template>
      <ElTabPane v-for="_ in tabs" :key="_" :name="_" :label="getLabel(_)" />
    </ElTabs>
  </div>
</template>

<style lang="scss">
.ui-layout-tabs {
  background-color: var(--el-bg-color);
  &_dropdown-item {
    padding: 0 !important;
    .el-link {
      display: block;
      width: 100%;
      padding: 5px 16px;
    }
  }
  .el-tabs {
    --el-tabs-header-height: 36px;
  }
  .el-tabs__header {
    min-height: 33px;
    margin-bottom: 0;
    padding: 0 6px;
  }
  .el-tabs__new-tab {
    border: none;
    min-width: 20px;
  }
  .el-tabs__nav-next, .el-tabs__nav-prev {
    line-height: 32px;
    font-size: 14px;
  }
  .el-tabs__nav {
    border-top: none !important;
  }
  .el-tabs__item {
    height: 28px;
    border: 1px solid var(--el-border-color-light) !important;
    font-size: 13px;
    &:not(:last-child) {
      margin-right: 6px;
    }
  }
}
</style>
